package com.scalar.chiptrack.sales.actions;

import java.util.ArrayList;
import java.util.HashMap;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;

import org.apache.commons.beanutils.PropertyUtils;
import org.apache.struts.action.ActionForm;
import org.apache.struts.action.ActionForward;
import org.apache.struts.action.ActionMapping;

import com.scalar.ScalarException;
import com.scalar.chiptrack.ChipTrackAction;
import com.scalar.chiptrack.alarms.Alarm;
import com.scalar.chiptrack.commons.SessionKeys;
import com.scalar.chiptrack.db.DBTransaction;
import com.scalar.chiptrack.sales.LineItem;
import com.scalar.chiptrack.sales.SalesOrder;
import com.scalar.chiptrack.sales.dao.SalesOrderDAO;
import com.scalar.chiptrack.sales.forms.SalesOrderForm;
import com.scalar.chiptrack.users.User;


/**
 * Implementation of <strong>Action</strong> that gives customers list,
 * search with customer name, create sales order
 *
 * @author Kesava Kumar Achanala
 * @version $Revision: 1.3 $ $Date: 2007/06/12 15:10:03 $
 */

public final class CustomerOrderAction extends ChipTrackAction {


    // ----------------------------------------------------- Instance Variables

    private static final String ACTION_NAME = "/onlineOrder.do" ;  // Added by Basha (08/08/2003)

    // --------------------------------------------------------- Public Methods

    public ActionForward execute(ActionMapping mapping,
				 ActionForm form,
				 HttpServletRequest request,
				 HttpServletResponse response)
	throws Exception {

		// Extract attributes and parameters we will need
		SalesOrderForm subform = (SalesOrderForm) form;
		String action = request.getParameter("action");
                 
                 //Get the session, to retrieve the values
                 HttpSession session = request.getSession();
                 User user = (User)session.getAttribute (SessionKeys.USER_KEY);
                // Added by Basha (08/08/2003)
                if(user == null)
                {
	                session.setAttribute (SessionKeys.SOURCE_PAGE_KEY, ACTION_NAME + "?" + request.getQueryString());
                    return (mapping.findForward ("login"));
                }
                // Added by Basha (08/08/2003)

		// Validate the request parameters specified by the user
		HashMap errors = new HashMap();
                HashMap info = new HashMap();
                //System.out.println("In the action");
                if("NewSalesOrder".equals(action))
                {   
                    int selectedCustomer = user.getCustomerId();System.out.println("In the sales order " + selectedCustomer);
                    
                    //Set the customer details for this selected customer...
                    PropertyUtils.copyProperties(subform,SalesOrderDAO.getSalesOrderCustomerDetails(selectedCustomer+""));
                    
                    //Set the default lineItems...
                    request.setAttribute("lineItems",getLineItems(session));
                    
                    //Setting into the session as the collection in the options tag is need to put in jsp scope
                    session.setAttribute("shippingMethods",subform.getShippingMethods());
                    
                    //Set the shippingAddresses for the collection
                    session.setAttribute("shippingAddresses",subform.getShippingAddresses());                    
                    saveToken(request);
                    return (mapping.findForward("salesOrder"));
                } 
                else
                if("UpdateSalesOrder".equals(action))
                {
                     if(session.getAttribute("newShippingAddressId") != null) {
                         subform.setShippingAddressId(Integer.parseInt((String)session.getAttribute("newShippingAddressId")));
                     }

                     //For setting the shipping method 
                     subform.setShippingMethod(subform.getShippingAccount());
                     
                     request.setAttribute("salesOrderForm",subform);
                     
                    //Set the lineitems in the request,false is not to check for marketing limits
                     request.setAttribute("lineItems",loadLineItems(request,subform.getCustomerId(),errors,info,false));                     
                     session.setAttribute("maxLineItemNo",request.getAttribute("maxLineItemNo"));

                     //Setting into the request as the collection in the options tag is need to put in jsp scope
                     session.setAttribute("shippingMethods",session.getAttribute("shippingMethods"));
                                          
                     //Set the shippingAddresses for the collection
                     session.setAttribute("shippingAddresses",session.getAttribute("shippingAddresses"));
                         
                     errors = (HashMap)request.getAttribute("Errors");
                     if(!errors.isEmpty()) 
                          request.setAttribute(SessionKeys.ERROR_MESSAGES, errors);
                     
                        //saveErrors(request, errors);
                                      
                     saveToken(request);                                                               
                     return (mapping.findForward("salesOrder"));
                     
                }
                else                
                if("SubmitSalesOrder".equals(action))
                {   
                    if(session.getAttribute("newShippingAddressId") != null) {
                         subform.setShippingAddressId(Integer.parseInt((String)session.getAttribute("newShippingAddressId")));
                         session.removeAttribute("newShippingAddressId");
                    }
                    
                     //For setting the shipping method 
                     subform.setShippingMethod(subform.getShippingAccount());
                     
                    //Set the form values and lineitems values, to show in the confirmation page
                    session.setAttribute("salesOrderForm",subform);
                    
                    //Set the lineitems values , true for check for marketing limits
                    session.setAttribute("lineItems",loadLineItems(request,subform.getCustomerId(),errors,info,true));                     
                    session.setAttribute("maxLineItemNo",request.getAttribute("maxLineItemNo"));
                    errors = (HashMap)request.getAttribute("Errors");
                    if(!errors.isEmpty()) {
                          request.setAttribute(SessionKeys.ERROR_MESSAGES, errors);                          
                          return (mapping.findForward("salesOrder"));
                    }
                    
                    info = (HashMap)request.getAttribute("Info");
                    if(!info.isEmpty()) {
                        request.setAttribute(SessionKeys.INFO_MESSAGES,info);
                    }
                    saveToken(request);
                    return (mapping.findForward("confirmOrder"));   
                }
                else
                if("EditSalesOrder".equals(action))
                {
                    
                    request.setAttribute("salesOrderForm",session.getAttribute("salesOrderForm"));
                     
                    //Setting into the request as the collection in the options tag is need to put in jsp scope
                    session.setAttribute("shippingMethods",session.getAttribute("shippingMethods"));
                     
                    //Set the shippingAddresses for the collection
                    session.setAttribute("shippingAddresses",session.getAttribute("shippingAddresses"));                    
                    
                    //Set the lineitems values , true for check for marketing limits
                    //request.setAttribute("lineItems",loadLineItems(request,subform.getCustomerId(),errors,true));                     
                    request.setAttribute("lineItems", (ArrayList)request.getAttribute("lineItems"));
                    session.setAttribute("maxLineItemNo",session.getAttribute("maxLineItemNo"));
                    saveToken(request);
                    return (mapping.findForward("salesOrder"));                    
                }
                else
                if("ConfirmSalesOrder".equals(action))
                {
                    if(!isTokenValid(request)) {
                        errors.put("This SalesOrder is already submitted, If you want to change this salesOrder click ChangeOrderEntry on the left menu and modify..","");
                    }
                    resetToken(request);
                    
                    if(!errors.isEmpty()) {
                        request.setAttribute(SessionKeys.ERROR_MESSAGES, errors);
                        saveToken(request);
                        return (mapping.findForward("success"));
                    }
                    
                    
                    SalesOrder salesOrder = new SalesOrder();
                    PropertyUtils.copyProperties(salesOrder,(SalesOrderForm)session.getAttribute("salesOrderForm")); 
                    
                    if(SalesOrderDAO.isCustomerPOExists(salesOrder.getCustomerId(),salesOrder.getCustomerPO())) {
                        errors.put( ERROR_CUSTOMER_PO_ALREADY_EXISTS, null );
                        request.setAttribute(SessionKeys.ERROR_MESSAGES, errors);
                        
                        request.setAttribute("salesOrderForm",session.getAttribute("salesOrderForm"));
                     
                        //Setting into the request as the collection in the options tag is need to put in jsp scope
                        session.setAttribute("shippingMethods",session.getAttribute("shippingMethods"));
                     
                        //Set the shippingAddresses for the collection
                        session.setAttribute("shippingAddresses",session.getAttribute("shippingAddresses"));                    
                    
                        //Set the lineitems values , true for check for marketing limits
                        //request.setAttribute("lineItems",loadLineItems(request,subform.getCustomerId(),errors,true));                     
                        request.setAttribute("lineItems", (ArrayList)request.getAttribute("lineItems"));
                        session.setAttribute("maxLineItemNo",session.getAttribute("maxLineItemNo"));
                        saveToken(request);
                        return (mapping.findForward("salesOrder"));                    
                    }
                    
                    DBTransaction dbTransaction = null;
                    boolean success = false;
                    Alarm alarm = null;
                    int salesOrderId = -1;
                    
                    try {                       
                        //Begine Transaction
                        dbTransaction = DBTransaction.getInstance();
                        dbTransaction.begin();                        
                        
                        //Save the salesOrder details & get the salesOrderId
                        salesOrderId = SalesOrderDAO.saveOnlineOrder(dbTransaction, salesOrder, user.getUserId());
                       // System.out.println("Saved the onlineOrder " + salesOrderId);
                        //Save the LineItems..
                        SalesOrderDAO.insertOnlineLineItems(dbTransaction,salesOrderId,(ArrayList)session.getAttribute("lineItems"),user.getUserId());
                       // System.out.println("Saved the lineItems");
                        alarm = SalesOrderDAO.sendMailToSales(dbTransaction,user,salesOrderId,salesOrder.getComments());
                        
                        success = true;

                        request.setAttribute("salesOrderId",Integer.toString(salesOrderId));
                        
                    }
                    catch (ScalarException se) {
                        // Exception while updating user profile
                        // log it
                        se.printStackTrace();
                    }
                    finally {
                        // Rollback or Commit the Transaction
                        if (success == true) {
                                dbTransaction.commit();                            
                                errors.put("SalesOrder = " + (String)request.getAttribute("salesOrderId"), "Saved Successfully");
                                errors.put("Email ", " has been send to Sales Person");
                            
                            try {
                               //Notify all the reciepents                            
                               alarm.notifyAllRecipients(SalesOrder.getHtmlView(salesOrderId));
                            } catch(Exception exe)
                            {
                                  errors.put("Email ", ERROR_IN_SENDING_MAILS_TO_SALES_PERSON );
                            }
                    
                        }
                        else {
                            dbTransaction.rollback();
                            errors.put(ERROR_INTERNAL_SERVER_ERROR, ERROR_IN_SAVING_SALES_ORDER_DETAILS );
                            errors.put( ERROR_MESSAGE_CONTACT_SYS_ADMN, null );
                            session.setAttribute( SessionKeys.ERROR_REPORT_SUBJECT, " Error: Could Not Save Sales Order ");
                            session.setAttribute( SessionKeys.ERROR_REPORT, null );
                        }
                    }
                    
                    if(!errors.isEmpty()) 
                            request.setAttribute(SessionKeys.MESSAGES, errors);
                    
                    //Remove session variable
                    session.removeAttribute("lineItems");
                    session.removeAttribute("shippingMethods");
                    session.removeAttribute("salesOrderForm");
                    session.removeAttribute("shippingAddresses");
                   
                }
                
                //Please look at this return later(Where do we need this retrurned) ????
		return (mapping.findForward("success"));

    }
    
    private static ArrayList loadLineItems(HttpServletRequest request, int customerId, 
                        HashMap errors, HashMap info, boolean checkLimits) throws ScalarException
    {
        //Get the LineItem values
        String[] lineItem = request.getParameterValues("lineItemNo");
        String[] marketingPartNo = request.getParameterValues("marketingPartNo");
        String[] manufacturingPartNo = request.getParameterValues("manufacturingPartNo");
        String[] quantity = request.getParameterValues("quantity");
        String[] requestDate = request.getParameterValues("requestDate");
        String[] leadTime= request.getParameterValues("leadTime");
        
        //Loop thru all the elements and add to ArrayList elements,
        ArrayList lineItemsList = new ArrayList();
        LineItem lineItemInfo = null;
        for(int i=0; i<marketingPartNo.length; i++)
        {  
            if(lineItem[i].trim().equals(""))
                    lineItem[i] ="0";
          // System.out.println("marketing part number = " + marketingPartNo[i] + " , manufacturing part = " + manufacturingPartNo[i]);
             //if (Integer.parseInt(lineItem[i]) != 0) {
            if((marketingPartNo[i] !=  null)&&(!marketingPartNo[i].equals(""))
                    ||(manufacturingPartNo[i] != null)&&(!manufacturingPartNo[i].equals(""))){
                if(quantity[i].equals("")) 
                    quantity[i] = "0";                  
                
                
                 //Set all the lineitem parameters, marketingPartNo,manufacturingPartNo,unitPrice
                lineItemInfo = SalesOrderDAO.loadLineItemInfo(customerId, Integer.parseInt(lineItem[i]),
                                                      marketingPartNo[i], 
                                                      manufacturingPartNo[i], 
                                                      requestDate[i], leadTime[i],
                                                      Integer.parseInt(quantity[i]),
                                                      0.0f, 1);

                //It is not a valid information entered, so add it errors
                if(lineItemInfo == null) {
                    errors.put("LineItem No " + lineItem[i], "is not having valid partnumbers, please enter valid partnumbers");                       
                }
                
                                
                if(lineItemInfo == null) {
                    lineItemInfo = new LineItem();
                    lineItemInfo.setLineItemNo(Integer.parseInt(lineItem[i]));
                    lineItemInfo.setMarketingPartNo(marketingPartNo[i]);
                    lineItemInfo.setManufacturingPartNo(manufacturingPartNo[i]);
                    lineItemInfo.setQuantity(Integer.parseInt(quantity[i]));                    
                    lineItemInfo.setRequestDate(requestDate[i]);
                } else {
                    //Need to have the request date
                    if(requestDate[i].trim().length() == 0)
                        errors.put("LineItem No " + lineItem[i], "is not having request date, please enter valid date");   
                }
                //System.out.println("Unit Price = " + lineItemInfo.getUnitPrice() + " , Amount = " + lineItemInfo.getAmount());                
                request.setAttribute("maxLineItemNo",Integer.toString(Integer.parseInt(lineItem[i])+1));
                lineItemsList.add(lineItemInfo);
                
            }
       }
       
       request.setAttribute("Errors",errors);
       request.setAttribute("Info",info);
       
        return lineItemsList;
    }
    
    private static ArrayList getLineItems(HttpSession session) throws ScalarException
    {
        ArrayList lineItems = new ArrayList();
        for(int i=1; i<5; i++)
        {
            LineItem lineItem = new LineItem();
            lineItem.setLineItemNo(i);
            lineItems.add(lineItem); 
        }
        session.setAttribute("maxLineItemNo","5");
        
        return lineItems;
    }
    
    
}
